<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./style/index.css" />
    <title></title>
  </head>

  <body>
    <div class="container">
      <img class="image" id="image" />
      <div class="overlay" id="overlay">
        <div class="loading" id="loading"></div>
        <div class="success" id="success"></div>
        <div class="failure" id="failure"></div>
      </div>
    </div>

    <script src="./js/camera.js"></script>
    <script src="./js/socket.io.js"></script>
    <script>
      let timer = null;
      let parent = null;
      let webview = null;

      let retry = 0;
      let options = {};

      let isConnect = false;

      const image = document.getElementById("image");
      const loading = document.getElementById("loading");
      const success = document.getElementById("success");
      const failure = document.getElementById("failure");

      const camera = new Camera();

      const socket = io("http://192.168.1.229:8000", {
        transports: ["websocket"],
      });

      window.addEventListener("message", (event) => {
        const { type, data } = event.data;
        if (type === "open") {
          options = data;
          camera.open(options);
          setLoading(true, "正在连接");
          setSuccess(false);
          setFailure(false);
        }
        if (type === "close") {
          close(data);
        }
      });

      document.addEventListener("plusready", () => {
        webview = plus.webview.currentWebview();
        parent = webview.opener();

        camera.on("open", () => {
          send({ type: "open" });
          timer = setInterval(() => {
            const image_base64 = camera.captureImage();
            if (isConnect) {
              setLoading(false);
              setSuccess(false);
              setFailure(false);
              socket.emit("video_frame", { image_base64 });
            } else {
              image.setAttribute("src", image_base64);
            }
          }, 100);
        });

        camera.on("close", () => {
          send({ type: "close" });
          if (timer) clearInterval(timer);
        });

        socket.on("connect", () => {
          console.log("Socket.IO 连接成功");
          isConnect = true;
          setLoading(true, "连接成功");
          setSuccess(false);
          setFailure(false);
        });

        socket.on("disconnect", () => {
          console.log("Socket.IO 连接断开");
          isConnect = false;
          setLoading(false);
          setSuccess(false);
          setFailure(true, "连接断开");
        });

        socket.on("connect_error", (error) => {
          console.log("Socket.IO 连接错误", error.message);
          isConnect = false;
          if (retry === options.retryCount) {
            setLoading(false);
            setSuccess(false);
            setFailure(true, "连接错误");
            send({ type: "error", data: error.message });
          }
          retry += 1;
        });

        socket.on("recognition_frame", (event) => {
          const { image_base64 } = event;
          image.setAttribute("src", image_base64);
        });

        socket.on("recognition_info", (event) => {
          setLoading(false);
          setSuccess(true, "识别成功");
          setFailure(false);
          send({ type: "success", data: event });
        });
      });

      function send(data) {
        if (parent) {
          parent.evalJS(`window.postMessage(${JSON.stringify(data)}, "*");`);
        }
      }

      function close(ms = 2000) {
        setTimeout(() => {
          camera.close();
          socket.close();
          if (webview) webview.close();
        }, ms);
      }

      function setLoading(hidden, textContent) {
        loading.style.setProperty("display", hidden ? "flex" : "none");
        loading.textContent = textContent;
      }

      function setSuccess(hidden, textContent) {
        success.style.setProperty("display", hidden ? "block" : "none");
        success.textContent = textContent;
      }

      function setFailure(hidden, textContent) {
        failure.style.setProperty("display", hidden ? "block" : "none");
        failure.textContent = textContent;
      }
    </script>
  </body>
</html>
